/*
 ------------------------------------------------------------------------------
 Copyright (C) 1996-2001 Id Software, Inc.

 This file is part of the Quake source code.

 The Quake source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The Quake source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the Quake source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


//
// vector.h - vector math library
//


#ifndef __MATH_VECTOR_H__
#define __MATH_VECTOR_H__


extern glqVec2		vec2_origin;
extern glqVec3		vec3_origin;
extern glqVec4		vec4_origin;
extern glqVec5		vec5_origin;

/*
 ==============================================================================

 2D VECTOR

 ==============================================================================
*/

class glqVec2 {
public:
	float			x;
	float			y;

public:
					glqVec2 (void);
	explicit		glqVec2 (const float value);
	explicit		glqVec2 (const float x, const float y);

	float			operator [] (const int index) const;
	float &			operator [] (const int index);

	glqVec2 &		operator = (const glqVec2 &vec);
	bool			operator == (const glqVec2 &vec) const;
	bool			operator != (const glqVec2 &vec) const;

	glqVec2			operator - () const;

	glqVec2			operator + (const glqVec2 &vec) const;
	glqVec2			operator - (const glqVec2 &vec) const;
	glqVec2			operator * (const glqVec2 &vec) const;
	glqVec2			operator / (const glqVec2 &vec) const;
	glqVec2			operator + (const float value) const;
	glqVec2			operator - (const float value) const;
	glqVec2			operator * (const float value) const;
	glqVec2			operator / (const float value) const;

	glqVec2 &		operator += (const glqVec2 &vec);
	glqVec2 &		operator -= (const glqVec2 &vec);
	glqVec2 &		operator *= (const glqVec2 &vec);
	glqVec2 &		operator /= (const glqVec2 &vec);
	glqVec2 &		operator += (const float value);
	glqVec2 &		operator -= (const float value);
	glqVec2 &		operator *= (const float value);
	glqVec2 &		operator /= (const float value);

	bool			Compare (const glqVec2 &vec) const;
	bool			Compare (const glqVec2 &vec, const float epsilon) const;
	void			Set (const float value);
	void			Set (const float x, const float y);
	void			Clear (void);
	bool			IsCleared (void) const;
	void			Snap (void);
	void			Truncate (void);
	void			Clamp (const glqVec2 &min, const glqVec2 &max);
	void			Clamp (const float min, const float max);
	void			Average (const glqVec2 &vec1, const glqVec2 &vec2);
	float			Dot (const glqVec2 &vec) const;
	void			Lerp (const glqVec2 &from, const glqVec2 &to, const float frac);
	void			LerpFast (const glqVec2 &from, const glqVec2 &to, const float frac);
	float			Distance (const glqVec2 &vec) const;
	float			DistanceFast (const glqVec2 &vec) const;
	float			DistanceSqr (const glqVec2 &vec) const;
	float			Length (void) const;
	float			LengthFast (void) const;
	float			LengthSqr (void) const;
	float			Normalize (void);
	void			NormalizeFast (void);

	const float *	ToFloatPtr (void) const;
	float *			ToFloatPtr (void);

	const char *	ToString (int precision = 2) const;
};

INLINE glqVec2::glqVec2 (void){

}

INLINE glqVec2::glqVec2 (const float value){

	this->x = value;
	this->y = value;
}

INLINE glqVec2::glqVec2 (const float x, const float y){

	this->x = x;
	this->y = y;
}

INLINE float glqVec2::operator [] (const int index) const {

	return (&x)[index];
}

INLINE float &glqVec2::operator [] (const int index){

	return (&x)[index];
}

INLINE glqVec2 &glqVec2::operator = (const glqVec2 &vec){

	x = vec.x;
	y = vec.y;

	return *this;
}

INLINE bool glqVec2::operator == (const glqVec2 &vec) const {

	if (x != vec.x || y != vec.y)
		return false;

	return true;
}

INLINE bool glqVec2::operator != (const glqVec2 &vec) const {

	if (x == vec.x && y == vec.y)
		return false;

	return true;
}

INLINE glqVec2 glqVec2::operator - () const {

	return glqVec2(-x, -y);
}

INLINE glqVec2 glqVec2::operator + (const glqVec2 &vec) const {

	return glqVec2(x + vec.x, y + vec.y);
}

INLINE glqVec2 glqVec2::operator - (const glqVec2 &vec) const {

	return glqVec2(x - vec.x, y - vec.y);
}

INLINE glqVec2 glqVec2::operator * (const glqVec2 &vec) const {

	return glqVec2(x * vec.x, y * vec.y);
}

INLINE glqVec2 glqVec2::operator / (const glqVec2 &vec) const {

	return glqVec2(x / vec.x, y / vec.y);
}

INLINE glqVec2 glqVec2::operator + (const float value) const {

	return glqVec2(x + value, y + value);
}

INLINE glqVec2 glqVec2::operator - (const float value) const {

	return glqVec2(x - value, y - value);
}

INLINE glqVec2 glqVec2::operator * (const float value) const {

	return glqVec2(x * value, y * value);
}

INLINE glqVec2 glqVec2::operator / (const float value) const {

	float	scale = 1.0f / value;

	return glqVec2(x * scale, y * scale);
}

INLINE glqVec2 &glqVec2::operator += (const glqVec2 &vec){

	x += vec.x;
	y += vec.y;

	return *this;
}

INLINE glqVec2 &glqVec2::operator -= (const glqVec2 &vec){

	x -= vec.x;
	y -= vec.y;

	return *this;
}

INLINE glqVec2 &glqVec2::operator *= (const glqVec2 &vec){

	x *= vec.x;
	y *= vec.y;

	return *this;
}

INLINE glqVec2 &glqVec2::operator /= (const glqVec2 &vec){

	x /= vec.x;
	y /= vec.y;

	return *this;
}

INLINE glqVec2 &glqVec2::operator += (const float value){

	x += value;
	y += value;

	return *this;
}

INLINE glqVec2 &glqVec2::operator -= (const float value){

	x -= value;
	y -= value;

	return *this;
}

INLINE glqVec2 &glqVec2::operator *= (const float value){

	x *= value;
	y *= value;

	return *this;
}

INLINE glqVec2 &glqVec2::operator /= (const float value){

	float	scale = 1.0f / value;

	x *= scale;
	y *= scale;

	return *this;
}

INLINE bool glqVec2::Compare (const glqVec2 &vec) const {

	if (x != vec.x)
		return false;
	if (y != vec.y)
		return false;

	return true;
}

INLINE bool glqVec2::Compare (const glqVec2 &vec, const float epsilon) const {

	if (glqMath::FAbs(x - vec.x) > epsilon)
		return false;
	if (glqMath::FAbs(y - vec.y) > epsilon)
		return false;

	return true;
}

INLINE void glqVec2::Set (const float value){

	this->x = value;
	this->y = value;
}

INLINE void glqVec2::Set (const float x, const float y){

	this->x = x;
	this->y = y;
}

INLINE void glqVec2::Clear (void){

	x = 0.0f;
	y = 0.0f;
}

INLINE bool glqVec2::IsCleared (void) const {

	if (x != 0.0f || y != 0.0f)
		return false;

	return true;
}

INLINE void glqVec2::Snap (void){

	x = glqMath::Round(x);
	y = glqMath::Round(y);
}

INLINE void glqVec2::Truncate (void){

	x = glqMath::FloatToInt(x);
	y = glqMath::FloatToInt(y);
}

INLINE void glqVec2::Clamp (const glqVec2 &min, const glqVec2 &max){

	x = (x < min.x) ? min.x : (x > max.x) ? max.x : x;
	y = (y < min.y) ? min.y : (y > max.y) ? max.y : y;
}

INLINE void glqVec2::Clamp (const float min, const float max){

	x = (x < min) ? min : (x > max) ? max : x;
	y = (y < min) ? min : (y > max) ? max : y;
}

INLINE void glqVec2::Average (const glqVec2 &vec1, const glqVec2 &vec2){

	x = (vec1.x + vec2.x) * 0.5f;
	y = (vec1.y + vec2.y) * 0.5f;
}

INLINE float glqVec2::Dot (const glqVec2 &vec) const {

	return x * vec.x + y * vec.y;
}

INLINE void glqVec2::Lerp (const glqVec2 &from, const glqVec2 &to, const float frac){

	if (frac <= 0.0f){
		*this = from;
		return;
	}

	if (frac >= 1.0f){
		*this = to;
		return;
	}

	x = from.x + (to.x - from.x) * frac;
	y = from.y + (to.y - from.y) * frac;
}

INLINE void glqVec2::LerpFast (const glqVec2 &from, const glqVec2 &to, const float frac){

	x = from.x + (to.x - from.x) * frac;
	y = from.y + (to.y - from.y) * frac;
}

INLINE float glqVec2::Distance (const glqVec2 &vec) const {

	float	xd, yd;

	xd = vec.x - x;
	yd = vec.y - y;

	return glqMath::Sqrt(xd*xd + yd*yd);
}

INLINE float glqVec2::DistanceFast (const glqVec2 &vec) const {

	float	xd, yd;

	xd = vec.x - x;
	yd = vec.y - y;

	return glqMath::SqrtFast(xd*xd + yd*yd);
}

INLINE float glqVec2::DistanceSqr (const glqVec2 &vec) const {

	float	xd, yd;

	xd = vec.x - x;
	yd = vec.y - y;

	return xd*xd + yd*yd;
}

INLINE float glqVec2::Length (void) const {

	return glqMath::Sqrt(x*x + y*y);
}

INLINE float glqVec2::LengthFast (void) const {

	return glqMath::SqrtFast(x*x + y*y);
}

INLINE float glqVec2::LengthSqr (void) const {

	return x*x + y*y;
}

INLINE float glqVec2::Normalize (void){

	float	length, invLength;

	length = glqMath::Sqrt(x*x + y*y);

	if (length){
		invLength = 1.0f / length;

		x *= invLength;
		y *= invLength;
	}

	return length;
}

INLINE void glqVec2::NormalizeFast (void){

	float	invLength;

	invLength = glqMath::RSqrt(x*x + y*y);

	x *= invLength;
	y *= invLength;
}

INLINE const float *glqVec2::ToFloatPtr (void) const {

	return &x;
}

INLINE float *glqVec2::ToFloatPtr (void){

	return &x;
}

/*
 ==============================================================================

 3D VECTOR

 ==============================================================================
*/

class glqVec3 {
public:
	float			x;
	float			y;
	float			z;

public:
					glqVec3 (void);
	explicit		glqVec3 (const float value);
	explicit		glqVec3 (const float x, const float y, const float z);

	float			operator [] (const int index) const;
	float &			operator [] (const int index);

	glqVec3 &		operator = (const glqVec3 &vec);
	bool			operator == (const glqVec3 &vec) const;
	bool			operator != (const glqVec3 &vec) const;

	glqVec3			operator - () const;

	glqVec3			operator + (const glqVec3 &vec) const;
	glqVec3			operator - (const glqVec3 &vec) const;
	glqVec3			operator * (const glqVec3 &vec) const;
	glqVec3			operator / (const glqVec3 &vec) const;
	glqVec3			operator + (const float value) const;
	glqVec3			operator - (const float value) const;
	glqVec3			operator * (const float value) const;
	glqVec3			operator / (const float value) const;

	glqVec3 &		operator += (const glqVec3 &vec);
	glqVec3 &		operator -= (const glqVec3 &vec);
	glqVec3 &		operator *= (const glqVec3 &vec);
	glqVec3 &		operator /= (const glqVec3 &vec);
	glqVec3 &		operator += (const float value);
	glqVec3 &		operator -= (const float value);
	glqVec3 &		operator *= (const float value);
	glqVec3 &		operator /= (const float value);

	bool			Compare (const glqVec3 &vec) const;
	bool			Compare (const glqVec3 &vec, const float epsilon) const;
	void			Set (const float value);
	void			Set (const float x, const float y, const float z);
	void			Clear (void);
	bool			IsCleared (void) const;
	void			Snap (void);
	void			Truncate (void);
	void			Clamp (const glqVec3 &min, const glqVec3 &max);
	void			Clamp (const float min, const float max);
	void			Average (const glqVec3 &vec1, const glqVec3 &vec2);
	float			Dot (const glqVec3 &vec) const;
	glqVec3			Cross (const glqVec3 &vec) const;
	void			Cross (const glqVec3 &vec1, const glqVec3 &vec2);
	void			Lerp (const glqVec3 &from, const glqVec3 &to, const float frac);
	void			LerpFast (const glqVec3 &from, const glqVec3 &to, const float frac);
	void			SLerp (const glqVec3 &from, const glqVec3 &to, const float frac);
	void			SLerpFast (const glqVec3 &from, const glqVec3 &to, const float frac);
	glqVec3			Reflect (const glqVec3 &normal) const;
	void			Reflect (const glqVec3 &vec, const glqVec3 &normal);
	glqVec3			ProjectOntoPlane (const glqVec3 &normal, const float overBounce);
	void			ProjectOntoPlane (const glqVec3 &vec, const glqVec3 &normal, const float overBounce);
	float			Distance (const glqVec3 &vec) const;
	float			DistanceFast (const glqVec3 &vec) const;
	float			DistanceSqr (const glqVec3 &vec) const;
	float			Length (void) const;
	float			LengthFast (void) const;
	float			LengthSqr (void) const;
	float			Normalize (void);
	void			NormalizeFast (void);
	void			NormalVectors (glqVec3 &right, glqVec3 &up) const;

	const float *	ToFloatPtr (void) const;
	float *			ToFloatPtr (void);
	const glqVec2 &	ToVec2 (void) const;
	glqVec2 &		ToVec2 (void);

	float			ToPitch (void) const;
	float			ToYaw (void) const;
	glqAngles		ToAngles (void) const;
	glqMat3			ToMat3 (void) const;
	const char *	ToString (int precision = 2) const;
};

INLINE glqVec3::glqVec3 (void){

}

INLINE glqVec3::glqVec3 (const float value){

	this->x = value;
	this->y = value;
	this->z = value;
}

INLINE glqVec3::glqVec3 (const float x, const float y, const float z){

	this->x = x;
	this->y = y;
	this->z = z;
}

INLINE float glqVec3::operator [] (const int index) const {

	return (&x)[index];
}

INLINE float &glqVec3::operator [] (const int index){

	return (&x)[index];
}

INLINE glqVec3 &glqVec3::operator = (const glqVec3 &vec){

	x = vec.x;
	y = vec.y;
	z = vec.z;

	return *this;
}

INLINE bool glqVec3::operator == (const glqVec3 &vec) const {

	if (x != vec.x || y != vec.y || z != vec.z)
		return false;

	return true;
}

INLINE bool glqVec3::operator != (const glqVec3 &vec) const {

	if (x == vec.x && y == vec.y && z == vec.z)
		return false;

	return true;
}

INLINE glqVec3 glqVec3::operator - () const {

	return glqVec3(-x, -y, -z);
}

INLINE glqVec3 glqVec3::operator + (const glqVec3 &vec) const {

	return glqVec3(x + vec.x, y + vec.y, z + vec.z);
}

INLINE glqVec3 glqVec3::operator - (const glqVec3 &vec) const {

	return glqVec3(x - vec.x, y - vec.y, z - vec.z);
}

INLINE glqVec3 glqVec3::operator * (const glqVec3 &vec) const {

	return glqVec3(x * vec.x, y * vec.y, z * vec.z);
}

INLINE glqVec3 glqVec3::operator / (const glqVec3 &vec) const {

	return glqVec3(x / vec.x, y / vec.y, z / vec.z);
}

INLINE glqVec3 glqVec3::operator + (const float value) const {

	return glqVec3(x + value, y + value, z + value);
}

INLINE glqVec3 glqVec3::operator - (const float value) const {

	return glqVec3(x - value, y - value, z - value);
}

INLINE glqVec3 glqVec3::operator * (const float value) const {

	return glqVec3(x * value, y * value, z * value);
}

INLINE glqVec3 glqVec3::operator / (const float value) const {

	float	scale = 1.0f / value;

	return glqVec3(x * scale, y * scale, z * scale);
}

INLINE glqVec3 &glqVec3::operator += (const glqVec3 &vec){

	x += vec.x;
	y += vec.y;
	z += vec.z;

	return *this;
}

INLINE glqVec3 &glqVec3::operator -= (const glqVec3 &vec){

	x -= vec.x;
	y -= vec.y;
	z -= vec.z;

	return *this;
}

INLINE glqVec3 &glqVec3::operator *= (const glqVec3 &vec){

	x *= vec.x;
	y *= vec.y;
	z *= vec.z;

	return *this;
}

INLINE glqVec3 &glqVec3::operator /= (const glqVec3 &vec){

	x /= vec.x;
	y /= vec.y;
	z /= vec.z;

	return *this;
}

INLINE glqVec3 &glqVec3::operator += (const float value){

	x += value;
	y += value;
	z += value;

	return *this;
}

INLINE glqVec3 &glqVec3::operator -= (const float value){

	x -= value;
	y -= value;
	z -= value;

	return *this;
}

INLINE glqVec3 &glqVec3::operator *= (const float value){

	x *= value;
	y *= value;
	z *= value;

	return *this;
}

INLINE glqVec3 &glqVec3::operator /= (const float value){

	float	scale = 1.0f / value;

	x *= scale;
	y *= scale;
	z *= scale;

	return *this;
}

INLINE bool glqVec3::Compare (const glqVec3 &vec) const {

	if (x != vec.x)
		return false;
	if (y != vec.y)
		return false;
	if (z != vec.z)
		return false;

	return true;
}

INLINE bool glqVec3::Compare (const glqVec3 &vec, const float epsilon) const {

	if (glqMath::FAbs(x - vec.x) > epsilon)
		return false;
	if (glqMath::FAbs(y - vec.y) > epsilon)
		return false;
	if (glqMath::FAbs(z - vec.z) > epsilon)
		return false;

	return true;
}

INLINE void glqVec3::Set (const float value){

	this->x = value;
	this->y = value;
	this->z = value;
}

INLINE void glqVec3::Set (const float x, const float y, const float z){

	this->x = x;
	this->y = y;
	this->z = z;
}

INLINE void glqVec3::Clear (void){

	x = 0.0f;
	y = 0.0f;
	z = 0.0f;
}

INLINE bool glqVec3::IsCleared (void) const {

	if (x != 0.0f || y != 0.0f || z != 0.0f)
		return false;

	return true;
}

INLINE void glqVec3::Snap (void){

	x = glqMath::Round(x);
	y = glqMath::Round(y);
	z = glqMath::Round(z);
}

INLINE void glqVec3::Truncate (void){

	x = glqMath::FloatToInt(x);
	y = glqMath::FloatToInt(y);
	z = glqMath::FloatToInt(z);
}

INLINE void glqVec3::Clamp (const glqVec3 &min, const glqVec3 &max){

	x = (x < min.x) ? min.x : (x > max.x) ? max.x : x;
	y = (y < min.y) ? min.y : (y > max.y) ? max.y : y;
	z = (z < min.z) ? min.z : (z > max.z) ? max.z : z;
}

INLINE void glqVec3::Clamp (const float min, const float max){

	x = (x < min) ? min : (x > max) ? max : x;
	y = (y < min) ? min : (y > max) ? max : y;
	z = (z < min) ? min : (z > max) ? max : z;
}

INLINE void glqVec3::Average (const glqVec3 &vec1, const glqVec3 &vec2){

	x = (vec1.x + vec2.x) * 0.5f;
	y = (vec1.y + vec2.y) * 0.5f;
	z = (vec1.z + vec2.z) * 0.5f;
}

INLINE float glqVec3::Dot (const glqVec3 &vec) const {

	return x * vec.x + y * vec.y + z * vec.z;
}

INLINE glqVec3 glqVec3::Cross (const glqVec3 &vec) const {

	return glqVec3(y * vec.z - z * vec.y, z * vec.x - x * vec.z, x * vec.y - y * vec.x);
}

INLINE void glqVec3::Cross (const glqVec3 &vec1, const glqVec3 &vec2){

	x = vec1.y * vec2.z - vec1.z * vec2.y;
	y = vec1.z * vec2.x - vec1.x * vec2.z;
	z = vec1.x * vec2.y - vec1.y * vec2.x;
}

INLINE void glqVec3::Lerp (const glqVec3 &from, const glqVec3 &to, const float frac){

	if (frac <= 0.0f){
		*this = from;
		return;
	}

	if (frac >= 1.0f){
		*this = to;
		return;
	}

	x = from.x + (to.x - from.x) * frac;
	y = from.y + (to.y - from.y) * frac;
	z = from.z + (to.z - from.z) * frac;
}

INLINE void glqVec3::LerpFast (const glqVec3 &from, const glqVec3 &to, const float frac){

	x = from.x + (to.x - from.x) * frac;
	y = from.y + (to.y - from.y) * frac;
	z = from.z + (to.z - from.z) * frac;
}

INLINE void glqVec3::SLerp (const glqVec3 &from, const glqVec3 &to, const float frac){

	float	omega, sinom, cosom;
	float	fScale, tScale;

	if (frac <= 0.0f){
		*this = from;
		return;
	}

	if (frac >= 1.0f){
		*this = to;
		return;
	}

	cosom = from.x * to.x + from.y * to.y + from.z * to.z;

	if ((1.0f - cosom) > 0.0f){
		omega = glqMath::ACos(cosom);
		sinom = 1.0f / glqMath::Sin(omega);

		fScale = glqMath::Sin((1.0f - frac) * omega) * sinom;
		tScale = glqMath::Sin(frac * omega) * sinom;
	}
	else {
		fScale = 1.0f - frac;
		tScale = frac;
	}

	x = from.x * fScale + to.x * tScale;
	y = from.y * fScale + to.y * tScale;
	z = from.z * fScale + to.z * tScale;
}

INLINE void glqVec3::SLerpFast (const glqVec3 &from, const glqVec3 &to, const float frac){

	float	omega, sinom, cosom;
	float	fScale, tScale;

	cosom = from.x * to.x + from.y * to.y + from.z * to.z;

	if ((1.0f - cosom) > 0.0f){
		omega = glqMath::ACos(cosom);
		sinom = 1.0f / glqMath::Sin(omega);

		fScale = glqMath::Sin((1.0f - frac) * omega) * sinom;
		tScale = glqMath::Sin(frac * omega) * sinom;
	}
	else {
		fScale = 1.0f - frac;
		tScale = frac;
	}

	x = from.x * fScale + to.x * tScale;
	y = from.y * fScale + to.y * tScale;
	z = from.z * fScale + to.z * tScale;
}

INLINE glqVec3 glqVec3::Reflect (const glqVec3 &normal) const {

	float	d;

	d = 2.0f * (x * normal.x + y * normal.y + z * normal.z);

	return glqVec3(x - normal.x * d, y - normal.y * d, z - normal.z * d);
}

INLINE void glqVec3::Reflect (const glqVec3 &vec, const glqVec3 &normal){

	float	d;

	d = 2.0f * (vec.x * normal.x + vec.y * normal.y + vec.z * normal.z);

	x = vec.x - normal.x * d;
	y = vec.y - normal.y * d;
	z = vec.z - normal.z * d;
}

INLINE glqVec3 glqVec3::ProjectOntoPlane (const glqVec3 &normal, const float overBounce){

	float	backOff;

	backOff = x * normal.x + y * normal.y + z * normal.z;

	if (backOff < 0.0f)
		backOff *= overBounce;
	else
		backOff /= overBounce;

	return glqVec3(x - normal.x * backOff, y - normal.y * backOff, z - normal.z * backOff);
}

INLINE void glqVec3::ProjectOntoPlane (const glqVec3 &vec, const glqVec3 &normal, const float overBounce){

	float	backOff;

	backOff = vec.x * normal.x + vec.y * normal.y + vec.z * normal.z;

	if (backOff < 0.0f)
		backOff *= overBounce;
	else
		backOff /= overBounce;

	x = vec.x - normal.x * backOff;
	y = vec.y - normal.y * backOff;
	z = vec.z - normal.z * backOff;
}

INLINE float glqVec3::Distance (const glqVec3 &vec) const {

	float	xd, yd, zd;

	xd = vec.x - x;
	yd = vec.y - y;
	zd = vec.z - z;

	return glqMath::Sqrt(xd*xd + yd*yd + zd*zd);
}

INLINE float glqVec3::DistanceFast (const glqVec3 &vec) const {

	float	xd, yd, zd;

	xd = vec.x - x;
	yd = vec.y - y;
	zd = vec.z - z;

	return glqMath::SqrtFast(xd*xd + yd*yd + zd*zd);
}

INLINE float glqVec3::DistanceSqr (const glqVec3 &vec) const {

	float	xd, yd, zd;

	xd = vec.x - x;
	yd = vec.y - y;
	zd = vec.z - z;

	return xd*xd + yd*yd + zd*zd;
}

INLINE float glqVec3::Length (void) const {

	return glqMath::Sqrt(x*x + y*y + z*z);
}

INLINE float glqVec3::LengthFast (void) const {

	return glqMath::SqrtFast(x*x + y*y + z*z);
}

INLINE float glqVec3::LengthSqr (void) const {

	return x*x + y*y + z*z;
}

INLINE float glqVec3::Normalize (void){

	float	length, invLength;

	length = glqMath::Sqrt(x*x + y*y + z*z);

	if (length){
		invLength = 1.0f / length;

		x *= invLength;
		y *= invLength;
		z *= invLength;
	}

	return length;
}

INLINE void glqVec3::NormalizeFast (void){

	float	invLength;

	invLength = glqMath::RSqrt(x*x + y*y + z*z);

	x *= invLength;
	y *= invLength;
	z *= invLength;
}

INLINE const float *glqVec3::ToFloatPtr (void) const {

	return &x;
}

INLINE float *glqVec3::ToFloatPtr (void){

	return &x;
}

INLINE const glqVec2 &glqVec3::ToVec2 (void) const {

	return *reinterpret_cast <const glqVec2 *> (this);
}

INLINE glqVec2 &glqVec3::ToVec2 (void){

	return *reinterpret_cast <glqVec2 *> (this);
}

/*
 ==============================================================================

 4D VECTOR

 ==============================================================================
*/

class glqVec4 {
public:
	float			x;
	float			y;
	float			z;
	float			w;

public:
					glqVec4 (void);
	explicit		glqVec4 (const float value);
	explicit		glqVec4 (const float x, const float y, const float z, const float w);

	float			operator [] (const int index) const;
	float &			operator [] (const int index);

	glqVec4 &		operator = (const glqVec4 &vec);
	bool			operator == (const glqVec4 &vec) const;
	bool			operator != (const glqVec4 &vec) const;

	glqVec4			operator - () const;

	glqVec4			operator + (const glqVec4 &vec) const;
	glqVec4			operator - (const glqVec4 &vec) const;
	glqVec4			operator * (const glqVec4 &vec) const;
	glqVec4			operator / (const glqVec4 &vec) const;
	glqVec4			operator + (const float value) const;
	glqVec4			operator - (const float value) const;
	glqVec4			operator * (const float value) const;
	glqVec4			operator / (const float value) const;

	glqVec4 &		operator += (const glqVec4 &vec);
	glqVec4 &		operator -= (const glqVec4 &vec);
	glqVec4 &		operator *= (const glqVec4 &vec);
	glqVec4 &		operator /= (const glqVec4 &vec);
	glqVec4 &		operator += (const float value);
	glqVec4 &		operator -= (const float value);
	glqVec4 &		operator *= (const float value);
	glqVec4 &		operator /= (const float value);

	bool			Compare (const glqVec4 &vec) const;
	bool			Compare (const glqVec4 &vec, const float epsilon) const;
	void			Set (const float value);
	void			Set (const float x, const float y, const float z, const float w);
	void			Clear (void);
	bool			IsCleared (void) const;
	void			Snap (void);
	void			Truncate (void);
	void			Clamp (const glqVec4 &min, const glqVec4 &max);
	void			Clamp (const float min, const float max);
	void			Average (const glqVec4 &vec1, const glqVec4 &vec2);
	float			Dot (const glqVec4 &vec) const;
	void			Lerp (const glqVec4 &from, const glqVec4 &to, const float frac);
	void			LerpFast (const glqVec4 &from, const glqVec4 &to, const float frac);
	float			Distance (const glqVec4 &vec) const;
	float			DistanceFast (const glqVec4 &vec) const;
	float			DistanceSqr (const glqVec4 &vec) const;
	float			Length (void) const;
	float			LengthFast (void) const;
	float			LengthSqr (void) const;
	float			Normalize (void);
	void			NormalizeFast (void);

	const float *	ToFloatPtr (void) const;
	float *			ToFloatPtr (void);
	const glqVec2 &	ToVec2 (void) const;
	glqVec2 &		ToVec2 (void);
	const glqVec3 &	ToVec3 (void) const;
	glqVec3 &		ToVec3 (void);

	const char *	ToString (int precision = 2) const;
};

INLINE glqVec4::glqVec4 (void){

}

INLINE glqVec4::glqVec4 (const float value){

	this->x = value;
	this->y = value;
	this->z = value;
	this->w = value;
}

INLINE glqVec4::glqVec4 (const float x, const float y, const float z, const float w){

	this->x = x;
	this->y = y;
	this->z = z;
	this->w = w;
}

INLINE float glqVec4::operator [] (const int index) const {

	return (&x)[index];
}

INLINE float &glqVec4::operator [] (const int index){

	return (&x)[index];
}

INLINE glqVec4 &glqVec4::operator = (const glqVec4 &vec){

	x = vec.x;
	y = vec.y;
	z = vec.z;
	w = vec.w;

	return *this;
}

INLINE bool glqVec4::operator == (const glqVec4 &vec) const {

	if (x != vec.x || y != vec.y || z != vec.z || w != vec.w)
		return false;

	return true;
}

INLINE bool glqVec4::operator != (const glqVec4 &vec) const {

	if (x == vec.x && y == vec.y && z == vec.z && w == vec.w)
		return false;

	return true;
}

INLINE glqVec4 glqVec4::operator - () const {

	return glqVec4(-x, -y, -z, -w);
}

INLINE glqVec4 glqVec4::operator + (const glqVec4 &vec) const {

	return glqVec4(x + vec.x, y + vec.y, z + vec.z, w + vec.w);
}

INLINE glqVec4 glqVec4::operator - (const glqVec4 &vec) const {

	return glqVec4(x - vec.x, y - vec.y, z - vec.z, w - vec.w);
}

INLINE glqVec4 glqVec4::operator * (const glqVec4 &vec) const {

	return glqVec4(x * vec.x, y * vec.y, z * vec.z, w * vec.w);
}

INLINE glqVec4 glqVec4::operator / (const glqVec4 &vec) const {

	return glqVec4(x / vec.x, y / vec.y, z / vec.z, w / vec.w);
}

INLINE glqVec4 glqVec4::operator + (const float value) const {

	return glqVec4(x + value, y + value, z + value, w + value);
}

INLINE glqVec4 glqVec4::operator - (const float value) const {

	return glqVec4(x - value, y - value, z - value, w - value);
}

INLINE glqVec4 glqVec4::operator * (const float value) const {

	return glqVec4(x * value, y * value, z * value, w * value);
}

INLINE glqVec4 glqVec4::operator / (const float value) const {

	float	scale = 1.0f / value;

	return glqVec4(x * scale, y * scale, z * scale, w * scale);
}

INLINE glqVec4 &glqVec4::operator += (const glqVec4 &vec){

	x += vec.x;
	y += vec.y;
	z += vec.z;
	w += vec.w;

	return *this;
}

INLINE glqVec4 &glqVec4::operator -= (const glqVec4 &vec){

	x -= vec.x;
	y -= vec.y;
	z -= vec.z;
	w -= vec.w;

	return *this;
}

INLINE glqVec4 &glqVec4::operator *= (const glqVec4 &vec){

	x *= vec.x;
	y *= vec.y;
	z *= vec.z;
	w *= vec.w;

	return *this;
}

INLINE glqVec4 &glqVec4::operator /= (const glqVec4 &vec){

	x /= vec.x;
	y /= vec.y;
	z /= vec.z;
	w /= vec.w;

	return *this;
}

INLINE glqVec4 &glqVec4::operator += (const float value){

	x += value;
	y += value;
	z += value;
	w += value;

	return *this;
}

INLINE glqVec4 &glqVec4::operator -= (const float value){

	x -= value;
	y -= value;
	z -= value;
	w -= value;

	return *this;
}

INLINE glqVec4 &glqVec4::operator *= (const float value){

	x *= value;
	y *= value;
	z *= value;
	w *= value;

	return *this;
}

INLINE glqVec4 &glqVec4::operator /= (const float value){

	float	scale = 1.0f / value;

	x *= scale;
	y *= scale;
	z *= scale;
	w *= scale;

	return *this;
}

INLINE bool glqVec4::Compare (const glqVec4 &vec) const {

	if (x != vec.x)
		return false;
	if (y != vec.y)
		return false;
	if (z != vec.z)
		return false;
	if (w != vec.w)
		return false;

	return true;
}

INLINE bool glqVec4::Compare (const glqVec4 &vec, const float epsilon) const {

	if (glqMath::FAbs(x - vec.x) > epsilon)
		return false;
	if (glqMath::FAbs(y - vec.y) > epsilon)
		return false;
	if (glqMath::FAbs(z - vec.z) > epsilon)
		return false;
	if (glqMath::FAbs(w - vec.w) > epsilon)
		return false;

	return true;
}

INLINE void glqVec4::Set (const float value){

	this->x = value;
	this->y = value;
	this->z = value;
	this->w = value;
}

INLINE void glqVec4::Set (const float x, const float y, const float z, const float w){

	this->x = x;
	this->y = y;
	this->z = z;
	this->w = w;
}

INLINE void glqVec4::Clear (void){

	x = 0.0f;
	y = 0.0f;
	z = 0.0f;
	w = 0.0f;
}

INLINE bool glqVec4::IsCleared (void) const {

	if (x != 0.0f || y != 0.0f || z != 0.0f || w != 0.0f)
		return false;

	return true;
}

INLINE void glqVec4::Snap (void){

	x = glqMath::Round(x);
	y = glqMath::Round(y);
	z = glqMath::Round(z);
	w = glqMath::Round(w);
}

INLINE void glqVec4::Truncate (void){

	x = glqMath::FloatToInt(x);
	y = glqMath::FloatToInt(y);
	z = glqMath::FloatToInt(z);
	w = glqMath::FloatToInt(w);
}

INLINE void glqVec4::Clamp (const glqVec4 &min, const glqVec4 &max){

	x = (x < min.x) ? min.x : (x > max.x) ? max.x : x;
	y = (y < min.y) ? min.y : (y > max.y) ? max.y : y;
	z = (z < min.z) ? min.z : (z > max.z) ? max.z : z;
	w = (w < min.w) ? min.w : (w > max.w) ? max.w : w;
}

INLINE void glqVec4::Clamp (const float min, const float max){

	x = (x < min) ? min : (x > max) ? max : x;
	y = (y < min) ? min : (y > max) ? max : y;
	z = (z < min) ? min : (z > max) ? max : z;
	w = (w < min) ? min : (w > max) ? max : w;
}

INLINE void glqVec4::Average (const glqVec4 &vec1, const glqVec4 &vec2){

	x = (vec1.x + vec2.x) * 0.5f;
	y = (vec1.y + vec2.y) * 0.5f;
	z = (vec1.z + vec2.z) * 0.5f;
	w = (vec1.w + vec2.w) * 0.5f;
}

INLINE float glqVec4::Dot (const glqVec4 &vec) const {

	return x * vec.x + y * vec.y + z * vec.z + w * vec.w;
}

INLINE void glqVec4::Lerp (const glqVec4 &from, const glqVec4 &to, const float frac){

	if (frac <= 0.0f){
		*this = from;
		return;
	}

	if (frac >= 1.0f){
		*this = to;
		return;
	}

	x = from.x + (to.x - from.x) * frac;
	y = from.y + (to.y - from.y) * frac;
	z = from.z + (to.z - from.z) * frac;
	w = from.w + (to.w - from.w) * frac;
}

INLINE void glqVec4::LerpFast (const glqVec4 &from, const glqVec4 &to, const float frac){

	x = from.x + (to.x - from.x) * frac;
	y = from.y + (to.y - from.y) * frac;
	z = from.z + (to.z - from.z) * frac;
	w = from.w + (to.w - from.w) * frac;
}

INLINE float glqVec4::Distance (const glqVec4 &vec) const {

	float	xd, yd, zd, wd;

	xd = vec.x - x;
	yd = vec.y - y;
	zd = vec.z - z;
	wd = vec.w - w;

	return glqMath::Sqrt(xd*xd + yd*yd + zd*zd + wd*wd);
}

INLINE float glqVec4::DistanceFast (const glqVec4 &vec) const {

	float	xd, yd, zd, wd;

	xd = vec.x - x;
	yd = vec.y - y;
	zd = vec.z - z;
	wd = vec.w - w;

	return glqMath::SqrtFast(xd*xd + yd*yd + zd*zd + wd*wd);
}

INLINE float glqVec4::DistanceSqr (const glqVec4 &vec) const {

	float	xd, yd, zd, wd;

	xd = vec.x - x;
	yd = vec.y - y;
	zd = vec.z - z;
	wd = vec.w - w;

	return xd*xd + yd*yd + zd*zd + wd*wd;
}

INLINE float glqVec4::Length (void) const {

	return glqMath::Sqrt(x*x + y*y + z*z + w*w);
}

INLINE float glqVec4::LengthFast (void) const {

	return glqMath::SqrtFast(x*x + y*y + z*z + w*w);
}

INLINE float glqVec4::LengthSqr (void) const {

	return x*x + y*y + z*z + w*w;
}

INLINE float glqVec4::Normalize (void){

	float	length, invLength;

	length = glqMath::Sqrt(x*x + y*y + z*z + w*w);

	if (length){
		invLength = 1.0f / length;

		x *= invLength;
		y *= invLength;
		z *= invLength;
		w *= invLength;
	}

	return length;
}

INLINE void glqVec4::NormalizeFast (void){

	float	invLength;

	invLength = glqMath::RSqrt(x*x + y*y + z*z + w*w);

	x *= invLength;
	y *= invLength;
	z *= invLength;
	w *= invLength;
}

INLINE const float *glqVec4::ToFloatPtr (void) const {

	return &x;
}

INLINE float *glqVec4::ToFloatPtr (void){

	return &x;
}

INLINE const glqVec2 &glqVec4::ToVec2 (void) const {

	return *reinterpret_cast <const glqVec2 *> (this);
}

INLINE glqVec2 &glqVec4::ToVec2 (void){

	return *reinterpret_cast <glqVec2 *> (this);
}

INLINE const glqVec3 &glqVec4::ToVec3 (void) const {

	return *reinterpret_cast <const glqVec3 *> (this);
}

INLINE glqVec3 &glqVec4::ToVec3 (void){

	return *reinterpret_cast <glqVec3 *> (this);
}

/*
 ==============================================================================

 5D VECTOR

 ==============================================================================
*/

class glqVec5 {
public:
	float			x;
	float			y;
	float			z;
	float			s;
	float			t;

public:
					glqVec5 (void);
	explicit		glqVec5 (const float value);
	explicit		glqVec5 (const float x, const float y, const float z, const float s, const float t);

	float			operator [] (const int index) const;
	float &			operator [] (const int index);

	glqVec5 &		operator = (const glqVec5 &vec);
	bool			operator == (const glqVec5 &vec) const;
	bool			operator != (const glqVec5 &vec) const;

	glqVec5			operator - () const;

	glqVec5			operator + (const glqVec5 &vec) const;
	glqVec5			operator - (const glqVec5 &vec) const;
	glqVec5			operator * (const glqVec5 &vec) const;
	glqVec5			operator / (const glqVec5 &vec) const;
	glqVec5			operator + (const float value) const;
	glqVec5			operator - (const float value) const;
	glqVec5			operator * (const float value) const;
	glqVec5			operator / (const float value) const;

	glqVec5 &		operator += (const glqVec5 &vec);
	glqVec5 &		operator -= (const glqVec5 &vec);
	glqVec5 &		operator *= (const glqVec5 &vec);
	glqVec5 &		operator /= (const glqVec5 &vec);
	glqVec5 &		operator += (const float value);
	glqVec5 &		operator -= (const float value);
	glqVec5 &		operator *= (const float value);
	glqVec5 &		operator /= (const float value);

	bool			Compare (const glqVec5 &vec) const;
	bool			Compare (const glqVec5 &vec, const float epsilon) const;
	void			Set (const float value);
	void			Set (const float x, const float y, const float z, const float s, const float t);
	void			Clear (void);
	bool			IsCleared (void) const;
	void			Snap (void);
	void			Truncate (void);
	void			Clamp (const glqVec5 &min, const glqVec5 &max);
	void			Clamp (const float min, const float max);
	void			Average (const glqVec5 &vec1, const glqVec5 &vec2);

	const float *	ToFloatPtr (void) const;
	float *			ToFloatPtr (void);
	const glqVec2 &	ToVec2 (void) const;
	glqVec2 &		ToVec2 (void);
	const glqVec3 &	ToVec3 (void) const;
	glqVec3 &		ToVec3 (void);
	const glqVec4 &	ToVec4 (void) const;
	glqVec4 &		ToVec4 (void);

	const char *	ToString (int precision = 2) const;
};

INLINE glqVec5::glqVec5 (void){

}

INLINE glqVec5::glqVec5 (const float value){

	this->x = value;
	this->y = value;
	this->z = value;
	this->s = value;
	this->t = value;
}

INLINE glqVec5::glqVec5 (const float x, const float y, const float z, const float s, const float t){

	this->x = x;
	this->y = y;
	this->z = z;
	this->s = s;
	this->t = t;
}

INLINE float glqVec5::operator [] (const int index) const {

	return (&x)[index];
}

INLINE float &glqVec5::operator [] (const int index){

	return (&x)[index];
}

INLINE glqVec5 &glqVec5::operator = (const glqVec5 &vec){

	x = vec.x;
	y = vec.y;
	z = vec.z;
	s = vec.s;
	t = vec.t;

	return *this;
}

INLINE bool glqVec5::operator == (const glqVec5 &vec) const {

	if (x != vec.x || y != vec.y || z != vec.z || s != vec.s || t != vec.t)
		return false;

	return true;
}

INLINE bool glqVec5::operator != (const glqVec5 &vec) const {

	if (x == vec.x && y == vec.y && z == vec.z && s == vec.s && t == vec.t)
		return false;

	return true;
}

INLINE glqVec5 glqVec5::operator - () const {

	return glqVec5(-x, -y, -z, -s, -t);
}

INLINE glqVec5 glqVec5::operator + (const glqVec5 &vec) const {

	return glqVec5(x + vec.x, y + vec.y, z + vec.z, s + vec.s, t + vec.t);
}

INLINE glqVec5 glqVec5::operator - (const glqVec5 &vec) const {

	return glqVec5(x - vec.x, y - vec.y, z - vec.z, s - vec.s, t - vec.t);
}

INLINE glqVec5 glqVec5::operator * (const glqVec5 &vec) const {

	return glqVec5(x * vec.x, y * vec.y, z * vec.z, s * vec.s, t * vec.t);
}

INLINE glqVec5 glqVec5::operator / (const glqVec5 &vec) const {

	return glqVec5(x / vec.x, y / vec.y, z / vec.z, s / vec.s, t / vec.t);
}

INLINE glqVec5 glqVec5::operator + (const float value) const {

	return glqVec5(x + value, y + value, z + value, s + value, t + value);
}

INLINE glqVec5 glqVec5::operator - (const float value) const {

	return glqVec5(x - value, y - value, z - value, s - value, t - value);
}

INLINE glqVec5 glqVec5::operator * (const float value) const {

	return glqVec5(x * value, y * value, z * value, s * value, t * value);
}

INLINE glqVec5 glqVec5::operator / (const float value) const {

	float	scale = 1.0f / value;

	return glqVec5(x * scale, y * scale, z * scale, s * scale, t * scale);
}

INLINE glqVec5 &glqVec5::operator += (const glqVec5 &vec){

	x += vec.x;
	y += vec.y;
	z += vec.z;
	s += vec.s;
	t += vec.t;

	return *this;
}

INLINE glqVec5 &glqVec5::operator -= (const glqVec5 &vec){

	x -= vec.x;
	y -= vec.y;
	z -= vec.z;
	s -= vec.s;
	t -= vec.t;

	return *this;
}

INLINE glqVec5 &glqVec5::operator *= (const glqVec5 &vec){

	x *= vec.x;
	y *= vec.y;
	z *= vec.z;
	s *= vec.s;
	t *= vec.t;

	return *this;
}

INLINE glqVec5 &glqVec5::operator /= (const glqVec5 &vec){

	x /= vec.x;
	y /= vec.y;
	z /= vec.z;
	s /= vec.s;
	t /= vec.t;

	return *this;
}

INLINE glqVec5 &glqVec5::operator += (const float value){

	x += value;
	y += value;
	z += value;
	s += value;
	t += value;

	return *this;
}

INLINE glqVec5 &glqVec5::operator -= (const float value){

	x -= value;
	y -= value;
	z -= value;
	s -= value;
	t -= value;

	return *this;
}

INLINE glqVec5 &glqVec5::operator *= (const float value){

	x *= value;
	y *= value;
	z *= value;
	s *= value;
	t *= value;

	return *this;
}

INLINE glqVec5 &glqVec5::operator /= (const float value){

	float	scale = 1.0f / value;

	x *= scale;
	y *= scale;
	z *= scale;
	s *= scale;
	t *= scale;

	return *this;
}

INLINE bool glqVec5::Compare (const glqVec5 &vec) const {

	if (x != vec.x)
		return false;
	if (y != vec.y)
		return false;
	if (z != vec.z)
		return false;
	if (s != vec.s)
		return false;
	if (t != vec.t)
		return false;

	return true;
}

INLINE bool glqVec5::Compare (const glqVec5 &vec, const float epsilon) const {

	if (glqMath::FAbs(x - vec.x) > epsilon)
		return false;
	if (glqMath::FAbs(y - vec.y) > epsilon)
		return false;
	if (glqMath::FAbs(z - vec.z) > epsilon)
		return false;
	if (glqMath::FAbs(s - vec.s) > epsilon)
		return false;
	if (glqMath::FAbs(t - vec.t) > epsilon)
		return false;

	return true;
}

INLINE void glqVec5::Set (const float value){

	this->x = value;
	this->y = value;
	this->z = value;
	this->s = value;
	this->t = value;
}

INLINE void glqVec5::Set (const float x, const float y, const float z, const float s, const float t){

	this->x = x;
	this->y = y;
	this->z = z;
	this->s = s;
	this->t = t;
}

INLINE void glqVec5::Clear (void){

	x = 0.0f;
	y = 0.0f;
	z = 0.0f;
	s = 0.0f;
	t = 0.0f;
}

INLINE bool glqVec5::IsCleared (void) const {

	if (x != 0.0f || y != 0.0f || z != 0.0f || s != 0.0f || t != 0.0f)
		return false;

	return true;
}

INLINE void glqVec5::Snap (void){

	x = glqMath::Round(x);
	y = glqMath::Round(y);
	z = glqMath::Round(z);
	s = glqMath::Round(s);
	t = glqMath::Round(t);
}

INLINE void glqVec5::Truncate (void){

	x = glqMath::FloatToInt(x);
	y = glqMath::FloatToInt(y);
	z = glqMath::FloatToInt(z);
	s = glqMath::FloatToInt(s);
	t = glqMath::FloatToInt(t);
}

INLINE void glqVec5::Clamp (const glqVec5 &min, const glqVec5 &max){

	x = (x < min.x) ? min.x : (x > max.x) ? max.x : x;
	y = (y < min.y) ? min.y : (y > max.y) ? max.y : y;
	z = (z < min.z) ? min.z : (z > max.z) ? max.z : z;
	s = (s < min.s) ? min.s : (s > max.s) ? max.s : s;
	t = (t < min.t) ? min.t : (t > max.t) ? max.t : t;
}

INLINE void glqVec5::Clamp (const float min, const float max){

	x = (x < min) ? min : (x > max) ? max : x;
	y = (y < min) ? min : (y > max) ? max : y;
	z = (z < min) ? min : (z > max) ? max : z;
	s = (s < min) ? min : (s > max) ? max : s;
	t = (t < min) ? min : (t > max) ? max : t;
}

INLINE void glqVec5::Average (const glqVec5 &vec1, const glqVec5 &vec2){

	x = (vec1.x + vec2.x) * 0.5f;
	y = (vec1.y + vec2.y) * 0.5f;
	z = (vec1.z + vec2.z) * 0.5f;
	s = (vec1.s + vec2.s) * 0.5f;
	t = (vec1.t + vec2.t) * 0.5f;
}

INLINE const float *glqVec5::ToFloatPtr (void) const {

	return &x;
}

INLINE float *glqVec5::ToFloatPtr (void){

	return &x;
}

INLINE const glqVec2 &glqVec5::ToVec2 (void) const {

	return *reinterpret_cast <const glqVec2 *> (this);
}

INLINE glqVec2 &glqVec5::ToVec2 (void){

	return *reinterpret_cast <glqVec2 *> (this);
}

INLINE const glqVec3 &glqVec5::ToVec3 (void) const {

	return *reinterpret_cast <const glqVec3 *> (this);
}

INLINE glqVec3 &glqVec5::ToVec3 (void){

	return *reinterpret_cast <glqVec3 *> (this);
}

INLINE const glqVec4 &glqVec5::ToVec4 (void) const {

	return *reinterpret_cast <const glqVec4 *> (this);
}

INLINE glqVec4 &glqVec5::ToVec4 (void){

	return *reinterpret_cast <glqVec4 *> (this);
}


#endif	// __MATH_VECTOR_H__